package com.lanhai.fnstore.dispatch;

import java.util.List;

import com.lanhai.fnstore.cache.AgvCache;
import com.lanhai.fnstore.cache.AgvItem;
import com.lanhai.fnstore.cache.EstimateCache;
import com.lanhai.fnstore.cache.MountCache;
import com.lanhai.fnstore.cache.ParkCache;
import com.lanhai.fnstore.cache.ParkItem;
import com.lanhai.fnstore.cache.ParkRelationCache;
import com.lanhai.fnstore.cache.PowerCache;
import com.lanhai.fnstore.cache.ProcessCache;
import com.lanhai.fnstore.cache.ProcessSelectTypeEnum;
import com.lanhai.fnstore.cache.RoadCache;
import com.lanhai.fnstore.cache.StationGroupCache;
import com.lanhai.fnstore.queue.DispatchQueue;
import com.lanhai.fnstore.queue.DispatchUnit;
import com.lanhai.fnstore.queue.TargetCmdEnum;

/**
 * 点位事件
 * 
 * @author virus408
 *
 */
public class ParkEvent {
	/**
	 * 到达判断点
	 * 
	 * @param agv
	 * @param park
	 * @return
	 */
	public static void arrivedDecide(AgvItem agv, ParkItem park, AgvData data) {

		//// 先更新装卸情况
		AgvMountState mobj = new AgvMountState();
		mobj.setUpHasTrans(false);
		mobj.setDownHasTrans(false);
		mobj.setDownFull(data.isDownFull());
		mobj.setUpFull(data.isUpFull());
		if (agv.isUpTrans() == false) {
			// 上层不能传输=上层已传输完成
			mobj.setUpHasTrans(true);
		}
		if (agv.isDownTrans() == false) {
			// 下层不能传输=下层已传输完成
			mobj.setDownHasTrans(true);
		}
		MountCache.mountAgv(agv.getAgvId(), mobj);

		//// 装卸分配工位
		String nextProcess = "";
		String nextProcess2 = null;
		if (park.getParkNo() == 15) {
			// 进入测试的点(防止人工拿货)
			if (mobj.isDownFull() == false) {
				nextProcess = "测试下料"; // 小车是空的
				nextProcess2 = "测试下料2组"; 
			} else {
				nextProcess = "测试上料"; // 小车有料
				nextProcess2 = "测试上料2组"; 
			}
			// 测试：让小车去仓库，跑线
			if (mobj.isDownFull() == false) {
				AgvResolve.AgvToRoad(agv, park.getRouteRoad());
			}
			return;
		} else if (park.getParkNo() == 12) {
			// 进入仓库的点(防止人工拿货)
			if (mobj.isDownFull() == false) {
				nextProcess = "仓库下料"; // 小车是空的
			} else {
				nextProcess = "仓库上料"; // 小车有料
			}
			// 测试：让小车去测试工序，跑线
			if (mobj.isDownFull() == false) {
				AgvResolve.AgvToRoad(agv, park.getRouteRoad());
			}
		}

		// 测试机台，电量低于80%+空车，就需要充电
		if (park.getParkNo() == 15 && data.isDownFull() == false && data.getPower() <= 80) {
			// 拿到可用的机台
			List<String> sglist = StationGroupCache.getCanUseStationGroupByWeight();
			// 可用机台中可用的充电点位
			int powerNO = PowerCache.getPowerNo(sglist);
			if (powerNO > 0) {
				String parkname = ParkCache.getParkName(powerNO);
				// 锁充电桩
				PowerCache.lockPower(powerNO, parkname, true);
				// 去充电
				int powerroad = ParkCache.getSourceRoad(powerNO);
				AgvResolve.AgvToRoad(agv, powerroad);
				return;
			} else {
				// 去唤醒充好电的小车离开，本车继续后续的工序
				int powp = PowerCache.getPowerFullPark(10);
				if (powp > 0) {
					String parkname = ParkCache.getParkName(powp);
					// 释放充电桩
					PowerCache.lockPower(powp, parkname, false);
					 
					//驱动停在充电桩上的小车
					AgvItem powragv = AgvCache.getAgvByPark(powp);
					if (powragv != null) { 
						// 回到主路
						AgvResolve.AgvToRoad(powragv, 0);
						// 当前点位的小车处理，交给下一个周期的指令去判断
						return;
					}
				} else {
					// 其它充电桩充电时间不够，小车继续后续的路线处理
					if (data.getPower() <= 40) {
						// 强制路线，不让小车干活
						AgvResolve.AgvToRoad(agv, 105);
					}
				}
			}

		} else if (park.getParkNo() == 12) {
			// 仓库判断点 只有空小车和其电量低了80才做此处理
			if (data.isDownFull() == false && data.getPower() <= 80) {
				// 电量不足，不用参与此传输
				// 前方有交管区，直接开过去等交管
				AgvResolve.AgvToRoad(agv, park.getRouteRoad());
				return;
			}
		}

		// 先判断对接设备组
		ProcessSelectTypeEnum selectType = ProcessCache.getTypeByProcess(nextProcess);
		List<Integer> pitList = null;
		switch (selectType) {
		case WeightAndNum:
			pitList = StationGroupCache.getCanUseParkNoListByWeightAndNum(nextProcess, nextProcess2,agv.getNextCmd());
			break;
		case Num:
			pitList = StationGroupCache.getCanUseParkNoListByNum(nextProcess,agv.getNextCmd());
			break;
		case Weight:
			pitList = StationGroupCache.getCanUseParkNoListByWeight(nextProcess,agv.getNextCmd());
			break;
		}

		ParkItem toTrans = ParkCache.getCanTransPark(pitList, selectType);
		if (toTrans == null) {
			// 来路上锁
			RoadCache.lockRoad(park.getSourceRoad(), true);
		} else {

			// 把对应的设备分组锁住
			StationGroupCache.lockGroup(toTrans.getStationGroup(), agv.getAgvId());
			// 分配小车路线
			AgvResolve.AgvToRoad(agv, toTrans.getSourceRoad());

			// 本判断点处理结束，解锁
			RoadCache.lockRoad(park.getSourceRoad(), false);
			// 通知预判断点释放一辆小车
			AgvResolve.NoticeEstimate(park.getParkNo());
		}
	}

	/**
	 * 到达资源释放点
	 * 
	 * @param agv
	 * @param park
	 * @return
	 */
	public static void arrivedRelease(AgvItem agv, ParkItem park) {
		// 解锁小车对应的设备分组
		StationGroupCache.unlockForAgv(agv.getAgvId());

		// 触发装卸分配工位的释放事件 :点位
		int readyParkNo = ParkRelationCache.getDecideParkNo(park.getParkNo());
		if (readyParkNo > 0) {
			DispatchUnit dus = new DispatchUnit();
			dus.setParkNo(readyParkNo);
			dus.setTarget(TargetCmdEnum.NoticeDecide);
			DispatchQueue.Push(dus);
		}

		// 执行后面的路线
		AgvResolve.AgvToRoad(agv, park.getTargetRoad());

	}

	/**
	 * 到达预判断位
	 * 
	 * @param agv
	 * @param park
	 */
	public static void arrivedEstimate(AgvItem agv, ParkItem park) {
		int decideParkNo = ParkRelationCache.getDecideParkNoByEstimate(park.getParkNo());
		ParkItem decidePark = ParkCache.getParkByNo(decideParkNo); // 装卸判断点
		if (decidePark == null)
			return;

		if (RoadCache.roadIsLock(decidePark.getSourceRoad())) {
			// 有车在行驶中，不处理，停野车
			EstimateCache.stopAgv(decideParkNo, agv.getAgvId());
			AgvResolve.AgvStopOrStart(agv, true);
		} else {
			// 没有锁，开过去
			int troad = ParkCache.getSourceRoad(decideParkNo);
			RoadCache.lockRoad(troad, true);
			AgvResolve.AgvToRoad(agv, troad);
		}
	}

	public static void arrivedPower(AgvItem agv, ParkItem park) {
		// 锁充电桩,防止人工操作充电，一并占位
		PowerCache.lockPower(park.getParkNo(), park.getParkName(), true);
	}

	public static void arrivedTrans(AgvItem agv, ParkItem park) {
		// 把对应的设备分组锁住,防止人工拖车进入强制传输
		StationGroupCache.lockGroup(park.getStationGroup(), agv.getAgvId());
	}
}
